module IFU(
    input wire clk,
    input wire reset,
    input wire br_taken,
    input wire[31:0]br_target,
    input wire block,
    output wire[31:0] inst,
    output wire[31:0] pc_o,
    output wire exc,
    output wire[ 5:0] ecode,
    output wire esubcode,
    output wire[31:0] badv,
    //
    output wire          rd_req,
    output wire[2 :0] rd_type,
    output wire[31:0] rd_addr,
    input  wire       rd_rdy,
    input  wire      ret_valid,
    input  wire     ret_last,
    input  wire[31:0] ret_data,

    output  wire      wr_req,//写请�?
    output  wire[2 :0] wr_type,
    output  wire[31:0] wr_addr,//写首地址
    output  wire[3 :0] wr_wstrb,
    output  wire[127:0] wr_data,
    input   wire      wr_rdy,
   //

    output wire IFU_ready
);
reg [31:0] pc;
wire[31:0] next_pc;
//IF ID EX MEM
//LD LD LD ST
assign ecode = 6'h08;
assign esubcode = 0;
assign exc = pc[1:0] != 0;
assign badv = pc;


always@(posedge clk)begin
    if(reset)pc<=32'h1BFFFFFC;
    else begin
        if(!block)begin
            pc<=next_pc;
        end
    end
end

wire cache_ok_o;
wire cache_addr_ok_o;
wire[31:0] addr_into_cache;
wire [31:0] cache_data_out;

assign IFU_ready= cache_ok_o & cache_addr_ok_o ;
assign next_pc = br_taken ? br_target : 
                 exc ? 32'h1BFFFFFC : pc + 4;
assign addr_into_cache = block ? pc : next_pc;

wire[19:0] tag_into_cache=addr_into_cache[31:12];
wire[7:0] index_into_cache=addr_into_cache[11:4];
wire[7:0] offset_into_cache=addr_into_cache[3:0];

cache cache0(
    .clk_g(clk),
    .resetn(~reset),
//cpu<->cache
    .valid(~reset),
    .op(0),
    .index(index_into_cache),
    .tag(tag_into_cache),
    .offset(offset_into_cache),
    .wstrb(0),
    .wdata(0),
    .addr_ok(cache_addr_ok_o),
    .data_ok(cache_ok_o),
    .rdata(cache_data_out),
    .is_uncache(0),
//cache<->axi
    .rd_req(rd_req),
    .rd_type(rd_type),
    .rd_addr(rd_addr),
    .rd_rdy(rd_rdy),
    .ret_valid(ret_valid),
    .ret_last(ret_last),
    .ret_data(ret_data),
    
    .wr_req(),
    .wr_type(),
    .wr_addr(),
    .wr_wstrb(),
    .wr_data(),
    .wr_rdy(1)
);

assign pc_o=pc;
assign inst = (reset | (pc==32'h1BFFFFFC)) | exc ? 32'h02800000 : cache_data_out;
endmodule